<?php
class Test_Event_Exception_Stub extends Exception {
	public function __construct($sMessage, $iCode){
		parent::__construct($sMessage, $iCode);
		new Event_Exception();
	}
}
class Test_Event_Exception extends PHPUnit_Framework_TestCase {
	private $aasParam = array(
		'testTheExceptionThrownIsAccessible' => array(
			'sMessage' => 'testTheExceptionThrownIsAccessible',
			'iCode' => 1002
		)
	);
	
	public function setup(){
		Test_Event_Exception_Handler::$oEvent = null;
	}
	
	private function getEvent($sMessage, $iCode){
		new Test_Event_Exception_Stub($sMessage, $iCode); # triggers and should populate Test_Event_Exception_Handler::$oEvent
		$oEvent = Test_Event_Exception_Handler::$oEvent;
		$this->assertFalse(is_null($oEvent), 'The event was not found');
		$this->assertTrue($oEvent instanceof Event_Exception, 'Event is of the wrong type');
		return $oEvent;
	}
		
	public function testMessageAndCodeAreAccessibleThroughTheParams(){
		$sMessage = __METHOD__;
		$iCode = 1001;
		$oEvent = $this->getEvent($sMessage, $iCode);
		
		$asParam = $oEvent->getParams();
		# is everything in place?
		$this->assertFalse(empty($asParam), 'There should be params in this event');
		
		$this->assertTrue(isset($asParam['message']), 'A message should be available');
		$this->assertTrue(isset($asParam['code']), 'A code should be available');

		$this->assertEquals($sMessage, $asParam['message'], 'The message does not match');
		$this->assertEquals($iCode, $asParam['code'], 'The code does not match');
	}
	
	public function testTheExceptionThrownIsAccessible(){
		$sMessage = __METHOD__;
		$iCode = 1002;
		$oEvent = $this->getEvent($sMessage, $iCode);
		
		$oEx = $oEvent->getException();
		
		$this->assertTrue($oEx instanceof Test_Event_Exception_Stub, 'An improper type of Exception is returned');
		$this->assertEquals($sMessage, $oEx->getMessage(), 'The message does not match');
		$this->assertEquals($iCode, $oEx->getCode(), 'The code does not match');
	}
	
	public function testTheSourceThrowingIsAccessible(){
		$sMessage = __METHOD__;
		$iCode = 1003;
		$oEvent = $this->getEvent($sMessage, $iCode);
		
		$oSource = $oEvent->getSource();
		
		$this->assertTrue($oSource instanceof Test_Event_Exception, 'An improper type of Exception is returned');
	}
	public function testOnlyExceptionsCanTriggerTheseEvents(){
		try {
			new Event_Exception();
			$this->fail('Triggering from outside an Exception should not be possible');
		}
		catch (Exception $oEx){}
	}
}	
class Test_Event_Exception_Handler extends Event_Handler {
	public static $oEvent;
	public function onException(Event_Exception $oEvent){
		self::$oEvent = $oEvent;
	}
}
new Test_Event_Exception_Handler('Test_Event_Exception');